//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#include "ListClusteringTask.h"
#include "ListAncestorMol.h"

#include <iostream>
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
using namespace std;
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
ListClusteringTask::ListClusteringTask() {
  
  this->tasks     = new TListE <ClusteringTask> ();
  this->listRanks = NULL;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
ListClusteringTask::ListClusteringTask(TListE <String>* labels, ListRankStatus* listRanks) {
   
  this->tasks     = new TListE <ClusteringTask> ();
  this->listRanks = listRanks;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
ListClusteringTask::ListClusteringTask(const ListClusteringTask& listClusteringTask) {
  
  this->tasks     = new TListE <ClusteringTask> (listClusteringTask.tasks);
  this->listRanks = listClusteringTask.listRanks;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
ListClusteringTask::ListClusteringTask(const ListClusteringTask* listClusteringTask) {
  
  this->tasks     = new TListE <ClusteringTask> (listClusteringTask->tasks);
  this->listRanks = listClusteringTask->listRanks;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
ListClusteringTask::~ListClusteringTask() {
  
  if (this->tasks) delete tasks;
    
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void ListClusteringTask::Tasks(TListE <ClusteringTask>* tasks) {
  
  if (tasks) *(this->tasks) = *tasks;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void ListClusteringTask::ListRanks(ListRankStatus* listRanks) {
  
  this->listRanks = listRanks;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
TListE <ClusteringTask>* ListClusteringTask::Tasks(void) {
  
  return this->tasks;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
ListRankStatus* ListClusteringTask::ListRanks(void) {
  
  return this->listRanks;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool ListClusteringTask::CreateListTask(TListE <String>* labels, int sizePartition) {
  
  if (!labels || !labels->Length() || !this->listRanks) return false;
  
  int numberWorkers    = this->listRanks->RanksStatus()->Length() - 1;
  int numberPartitions = (labels->Length()/sizePartition) + ((!(labels->Length()%sizePartition))?0:1); 
  
  if (numberWorkers < 1) return false;
  
  int rank = -1;
    
  for (int i = 0; i < numberPartitions; i++) {
    
    int ini = i * sizePartition;
    int end = ((i + 1) < numberPartitions)?(((i + 1) * sizePartition) - 1):(labels->Length());
    
    ClusteringTask* task = new ClusteringTask(ini, end, rank, 0);
    
    rank = (rank == numberWorkers)?1:(rank + 1);
    
    this->tasks->Add(task);
    
  }
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool ListClusteringTask::CreateListTaskWithoutAssign(TListE <String>* labels, int sizePartition) {
  
  if (!labels || !labels->Length() || !this->listRanks) return false;
  
  int numberWorkers    = this->listRanks->RanksStatus()->Length() - 1;
  int numberPartitions = (labels->Length()/sizePartition) + ((!(labels->Length()%sizePartition))?0:1); 
  
  if (numberWorkers < 1) return false;
  
  for (int i = 0; i < numberPartitions; i++) {
    
    int ini = i * sizePartition;
    int end = ((i + 1) < numberPartitions)?(((i + 1) * sizePartition) - 1):(labels->Length());
    
    ClusteringTask* task = new ClusteringTask(ini, end, 0, 0);
    
    this->tasks->Add(task);
    
  }
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
ClusteringTask* ListClusteringTask::NextTask(int status) {
  
  this->tasks->SetInitial();
  while (this->tasks->SetNext())
    if (this->tasks->GetCurrent()->Status() == status)
      return this->tasks->GetCurrent();
  
  return NULL;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
ClusteringTask* ListClusteringTask::GetTaskByRank(int rank) {
  
  this->tasks->SetInitial();
  while (this->tasks->SetNext())
    if (this->tasks->GetCurrent()->Rank() == rank)
      return this->tasks->GetCurrent();
  
  return NULL;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
ListClusteringTask ListClusteringTask::operator=(const ListClusteringTask& listClusteringTask) {
  
  *(this->tasks)  = *(listClusteringTask.tasks);
  this->listRanks = listClusteringTask.listRanks;
  
  return *this;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
